package br.com.ema.maze.factory;

import br.com.ema.maze.components.Maze;
import br.com.ema.maze.components.MazeSpace;
import br.com.ema.maze.components.MazeWall;

/**
 * @author Emanuel Cruz Rodrigues -> emanuelcruzrodrigues@gmail.com
 *
 */
public class MazeParameterFactory extends MazeAbstractFactory<MazeParameters>{
	
	private MazeNearbyUpdater updater = new MazeNearbyUpdater();

	@Override
	public Maze buildMaze(MazeParameters parameters) {
		Maze maze = new Maze();
		
		createSpaces(parameters, maze);
		
		setNearbyInToSpaces(maze);
		
		setWallsInToSpaces(parameters, maze);
		
		return maze;
	}
	

	private void createSpaces(MazeParameters parameters, Maze maze) {
		for (int y = 0; y < parameters.getHeight(); y++) {
			for (int x = 0; x < parameters.getWidth(); x++) {
				maze.addSpace( new MazeSpace(x, y) );
			}
		}
	}

	private void setNearbyInToSpaces(Maze maze) {
		updater.updateNearby(maze);	
	}
	
	private void setWallsInToSpaces(MazeParameters parameters, Maze maze) {
		int spacesQuantity = parameters.getWidth() * parameters.getHeight();
		double percentage = parameters.getWallPercentage() / 100D;
		int wallsQuantity = (int) (spacesQuantity * percentage);
		int wallsSetted = 0;
		while(wallsSetted < wallsQuantity){
			MazeSpace space = null;
			do {
				int y = (int)(Math.random() * parameters.getHeight());
				int x = (int)(Math.random() * parameters.getWidth());
				space = maze.getSpace(x, y);
				
			} while ((space.getDecoration() != null && space.getDecoration() instanceof MazeWall));
			
			space.setDecoration(new MazeWall());
			wallsSetted ++;
		}
	}


	/* (non-Javadoc)
	 * @see br.com.ema.maze.factory.MazeAbstractFactory#getMazeConfiguration(java.lang.Object)
	 */
	@Override
	public MazeConfiguration getMazeConfiguration(MazeParameters parameters) {
		MazeConfiguration mazeConfiguration = new MazeConfiguration();
		mazeConfiguration.setStartCoordinates(parameters.getStartCoordinates());
		mazeConfiguration.setExitCoordinates(parameters.getExitCoordinates());
		mazeConfiguration.setPassageAllowersInterval(parameters.getWallPassageAllowerInterval());
		mazeConfiguration.setupCharactersFromMazeParameters(parameters);		
		return mazeConfiguration;
	}


}
